package com.atchangsha.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.atchangsha.system.common.to.PayTO;
import com.atchangsha.system.common.utils.Result;
import com.atchangsha.system.constant.MQConstant;
import com.atchangsha.system.constant.PayConstants;
import com.atchangsha.system.dto.PayDTO;
import com.atchangsha.system.entity.*;
import org.springframework.amqp.core.*;
import com.atchangsha.system.feign.ThirdPartyFeignService;
import com.atchangsha.system.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

@Service
@Slf4j
public class PayServiceImpl implements PayService {
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private ThirdPartyFeignService thirdPartyFeignService;
    @Resource
    private OrderService orderService;
    @Resource
    CustomerService customerService;
    @Resource
    FoodTableService foodTableService;
    @Resource
    WorkerService workerService;
    @Resource
    PointService pointService;
    @Resource
    SalesBillService salesBillService;
    @Resource
    private RedisTemplate<String, Integer> redisTemplate;
    @Resource
    private DirectExchange commonExchange;

    @Override
    public String pay(PayDTO payDTO) {
        String jsonString = JSON.toJSONString(payDTO);
        //存入MQ
        try {
            String orderId = payDTO.getOrderId().toString();
            String queueName = orderId;
            RabbitAdmin admin = new RabbitAdmin(rabbitTemplate);
            Properties queueProperties = admin.getQueueProperties(queueName);
            if (queueProperties == null) {
                //队列不存在
                //创建队列
                Queue queue = new Queue(queueName, true, false, false, null);
                admin.declareQueue(queue);
                //将队列与交换机进行绑定，路由key为订单号
                admin.declareBinding(BindingBuilder.bind(queue).to(commonExchange).with(orderId));
                //并存入订单消息
                CorrelationData correlationData = new CorrelationData();
                correlationData.setId(orderId);
                rabbitTemplate.convertAndSend(MQConstant.COMMON_EXCHANGE, queueName, new Message(jsonString.getBytes("UTF-8"), new MessageProperties()), correlationData);
            }

        } catch (Exception e) {
            log.error(PayConstants.PayEnum.ADD_FAIL.getMsg());
        }

        PayTO payTO = new PayTO();
        payTO.setOrderId(payDTO.getOrderId());
        payTO.setMoney(payDTO.getMoney());
        return thirdPartyFeignService.pay(payTO);
    }

    @Override
    @Transactional
    public void consumer(Map<String, String> map, HttpServletResponse httpServletResponse) {
        String queueName = map.get("out_trade_no");
        Properties properties = new RabbitAdmin(rabbitTemplate).getQueueProperties(queueName);
        if (properties == null) {
            //说明MQ中没有该订单
            log.error(PayConstants.PayEnum.NOT_ORDER.getMsg());
        }
        //说明MQ中有该订单
        Message message = rabbitTemplate.receive(queueName);
        String msg = "";
        try {
            msg = new String(message.getBody(), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error(PayConstants.PayEnum.RECEIVE_FAIL.getMsg());
        }
        PayDTO payDTO = JSON.parseObject(msg, PayDTO.class);
        // 获取订单号
        Long orderId = payDTO.getOrderId();
        // 从数据库中查询该订单
        OrderEntity orderEntity = orderService.getById(orderId);
        // 得到餐桌id
        Long foodTableId = orderEntity.getFoodTableId();
        // 更新餐桌状态
        FoodTableEntity tableEntity = foodTableService.getOne(new QueryWrapper<FoodTableEntity>().eq("id", foodTableId));
        tableEntity.setStatus("0");
        // 餐桌的当前人数修改成0
        tableEntity.setCurrentNumber(0L);

        if (!foodTableService.updateById(tableEntity)) {
            log.error(PayConstants.PayEnum.UPDATE_TABLE_FAIL.getMsg());
        }
        // 根据workerId获取员工信息
        Long workerId = payDTO.getWorkerId();
        WorkerEntity workerEntity = workerService.getById(workerId);
        //更新员工绩效
        workerEntity.setPerformance(workerEntity.getPerformance() + 1);
        if (!workerService.updateById(workerEntity)) {
            log.error(PayConstants.PayEnum.UPDATE_WORKER_FAIL.getMsg());
        }
        //根据电话获取会员信息
        String phone = payDTO.getPhone();
        // 是会员用户
        if (!StringUtils.isEmpty(phone)) {
            CustomerEntity customerEntity = customerService.getOne(new LambdaQueryWrapper<CustomerEntity>()
                    .eq(CustomerEntity::getPhone, phone));
            // 获取会员的积分信息
            Long pointId = customerEntity.getPointId();
            PointEntity pointEntity = pointService.getById(pointId);
            // 更新会员信息
            pointEntity.setPoint(pointEntity.getPoint() + (long) payDTO.getOriginalPrice());
            pointEntity.setPointSum(pointEntity.getPointSum() + (long) payDTO.getOriginalPrice());
            if (!pointService.updateById(pointEntity)) {
                log.error(PayConstants.PayEnum.UPDATE_MEMBER_FAIL.getMsg());
            }
        }
        // 逻辑删除订单信息
        orderEntity.setTime(new Date());
        orderEntity.setRemoveFlag("1");
        if (!orderService.updateById(orderEntity)) {
            log.error(PayConstants.PayEnum.UPDATE_ORDER_FAIL.getMsg());
        }
        SalesBillEntity salesBillEntity = new SalesBillEntity();
        salesBillEntity.setOrderId(orderId);
        //TODO 强转问题
        salesBillEntity.setPrice((float) payDTO.getOriginalPrice());
        salesBillEntity.setPriceAfter((float) payDTO.getMoney());
        salesBillEntity.setTime(new Date());
        if (!salesBillService.save(salesBillEntity)) {
            log.error(PayConstants.PayEnum.ADD_BILL_FAIL.getMsg());
        }

        boolean queue = new RabbitAdmin(rabbitTemplate).deleteQueue(queueName);
        if (!queue) {
            //删除队列失败
            log.error(PayConstants.PayEnum.DELETE_FAIL.getMsg());
        }
        try {
            httpServletResponse.sendRedirect("http://localhost:8080/home");
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    @Override
    @Transactional
    public Result payCash(PayDTO payDTO) {
        log.info("payDTO:{}", payDTO);
        // 获取订单号
        Long orderId = payDTO.getOrderId();
        // 从数据库中查询该订单
        OrderEntity orderEntity = orderService.getById(orderId);

        // 得到餐桌id
        Long foodTableId = orderEntity.getFoodTableId();
        // 更新餐桌状态
        FoodTableEntity tableEntity = foodTableService.getOne(new QueryWrapper<FoodTableEntity>().eq("id", foodTableId));
        tableEntity.setStatus("0");
        // 餐桌的当前人数修改成0
        tableEntity.setCurrentNumber(0L);

        if (!foodTableService.updateById(tableEntity)) {
            return Result.fail(PayConstants.PayEnum.UPDATE_TABLE_FAIL);
        }
        // 根据workerId获取员工信息
        Long workerId = payDTO.getWorkerId();
        WorkerEntity workerEntity = workerService.getById(workerId);
        //更新员工绩效
        workerEntity.setPerformance(workerEntity.getPerformance() + 1);
        if (!workerService.updateById(workerEntity)) {
            return Result.fail(PayConstants.PayEnum.UPDATE_WORKER_FAIL);
        }
        //根据电话获取会员信息
        String phone = payDTO.getPhone();
        // 是会员用户
        if (!StringUtils.isEmpty(phone)) {
            CustomerEntity customerEntity = customerService.getOne(new LambdaQueryWrapper<CustomerEntity>()
                    .eq(CustomerEntity::getPhone, phone));
            // 获取会员的积分信息
            Long pointId = customerEntity.getPointId();
            PointEntity pointEntity = pointService.getById(pointId);
            // 更新会员信息
            pointEntity.setPoint(pointEntity.getPoint() + (long) payDTO.getOriginalPrice());
            pointEntity.setPointSum(pointEntity.getPointSum() + (long) payDTO.getOriginalPrice());
            if (!pointService.updateById(pointEntity)) {
                return Result.fail(PayConstants.PayEnum.UPDATE_MEMBER_FAIL);
            }
        }
        // 逻辑删除订单信息
        orderEntity.setTime(new Date());
        orderEntity.setRemoveFlag("1");
        if (!orderService.updateById(orderEntity)) {
            return Result.fail(PayConstants.PayEnum.UPDATE_ORDER_FAIL);
        }
        SalesBillEntity salesBillEntity = new SalesBillEntity();
        salesBillEntity.setOrderId(orderId);
        //TODO 强转问题
        salesBillEntity.setPrice((float) payDTO.getOriginalPrice());
        salesBillEntity.setPriceAfter((float) payDTO.getMoney());
        salesBillEntity.setTime(new Date());
        if (!salesBillService.save(salesBillEntity)) {
            return Result.fail(PayConstants.PayEnum.ADD_BILL_FAIL);
        }
        redisTemplate.delete(orderId.toString());
        RabbitAdmin rabbitAdmin = new RabbitAdmin(rabbitTemplate);
        Properties queueProperties = rabbitAdmin.getQueueProperties(orderId.toString());
        if (queueProperties != null) {
            rabbitAdmin.deleteQueue(orderId.toString());
        }
        return Result.ok(PayConstants.PayEnum.CASH_MONEY_SUCCESS);
    }
}
